import { PromptVariable, PromptVariableValue } from '@/types/prompt';
import {
  extractVariables,
  validateVariable,
  validateAllVariables,
  replaceVariables,
  preprocessVariableValue,
  findUndefinedVariables,
  findUnusedVariables,
  generateInitialValues
} from '@/utils/variable-parser';

export interface VariableContext {
  template: string;
  variables: PromptVariable[];
  values: Record<string, PromptVariableValue>;
}

export interface VariableProcessResult {
  processedTemplate: string;
  processedValues: Record<string, PromptVariableValue>;
  errors?: string[];
  warnings?: string[];
}

export interface VariableMetadata {
  name: string;
  usage: number;
  lastUsed?: Date;
  averageLength?: number;
  commonValues?: string[];
}

/**
 * 变量管理服务
 * 负责处理提示词模板中的变量相关操作
 */
class VariableManagerService {
  private variableCache: Map<string, VariableMetadata> = new Map();
  private preprocessors: Map<string, (value: any) => any> = new Map();

  constructor() {
    this.initializePreprocessors();
  }

  /**
   * 初始化预处理器
   */
  private initializePreprocessors() {
    // 字符串预处理器
    this.preprocessors.set('uppercase', (value: any) => String(value).toUpperCase());
    this.preprocessors.set('lowercase', (value: any) => String(value).toLowerCase());
    this.preprocessors.set('capitalize', (value: any) => {
      const str = String(value);
      return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
    });
    this.preprocessors.set('trim', (value: any) => String(value).trim());
    this.preprocessors.set('snake_case', (value: any) => 
      String(value).replace(/\s+/g, '_').toLowerCase()
    );
    this.preprocessors.set('kebab-case', (value: any) => 
      String(value).replace(/\s+/g, '-').toLowerCase()
    );
    this.preprocessors.set('camelCase', (value: any) => {
      const str = String(value);
      return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
        return index === 0 ? word.toLowerCase() : word.toUpperCase();
      }).replace(/\s+/g, '');
    });
    
    // 数字预处理器
    this.preprocessors.set('round', (value: any) => Math.round(Number(value)));
    this.preprocessors.set('floor', (value: any) => Math.floor(Number(value)));
    this.preprocessors.set('ceil', (value: any) => Math.ceil(Number(value)));
    this.preprocessors.set('abs', (value: any) => Math.abs(Number(value)));
    
    // 日期预处理器
    this.preprocessors.set('date', (value: any) => {
      const date = new Date(value);
      return date.toLocaleDateString('zh-CN');
    });
    this.preprocessors.set('time', (value: any) => {
      const date = new Date(value);
      return date.toLocaleTimeString('zh-CN');
    });
    this.preprocessors.set('datetime', (value: any) => {
      const date = new Date(value);
      return date.toLocaleString('zh-CN');
    });
  }

  /**
   * 解析模板中的变量
   */
  parseTemplate(template: string): string[] {
    return extractVariables(template);
  }

  /**
   * 验证单个变量值
   */
  validateSingleVariable(
    variable: PromptVariable,
    value: PromptVariableValue
  ): { valid: boolean; error?: string } {
    return validateVariable(variable, value);
  }

  /**
   * 验证所有变量
   */
  validateVariables(
    variables: PromptVariable[],
    values: Record<string, PromptVariableValue>
  ): { valid: boolean; errors: string[] } {
    return validateAllVariables(variables, values);
  }

  /**
   * 处理变量值（应用预处理器）
   */
  processVariableValue(
    variable: PromptVariable,
    value: PromptVariableValue
  ): PromptVariableValue {
    let processedValue = value;

    // 应用预处理器
    if (variable.preprocessor && this.preprocessors.has(variable.preprocessor)) {
      const preprocessor = this.preprocessors.get(variable.preprocessor);
      if (preprocessor) {
        processedValue = preprocessor(processedValue);
      }
    }

    // 应用自定义预处理函数
    if (variable.preprocessFunction) {
      try {
        const func = new Function('value', variable.preprocessFunction);
        processedValue = func(processedValue);
      } catch (error) {
        console.error('Error in custom preprocessor:', error);
      }
    }

    return processedValue;
  }

  /**
   * 处理所有变量并替换模板
   */
  processTemplate(context: VariableContext): VariableProcessResult {
    const errors: string[] = [];
    const warnings: string[] = [];
    const processedValues: Record<string, PromptVariableValue> = {};

    // 验证变量
    const validation = this.validateVariables(context.variables, context.values);
    if (!validation.valid) {
      errors.push(...validation.errors);
    }

    // 查找未定义的变量
    const undefinedVars = findUndefinedVariables(context.template, context.variables);
    if (undefinedVars.length > 0) {
      warnings.push(`模板中包含未定义的变量: ${undefinedVars.join(', ')}`);
    }

    // 查找未使用的变量
    const unusedVars = findUnusedVariables(context.template, context.variables);
    if (unusedVars.length > 0) {
      warnings.push(`以下变量已定义但未在模板中使用: ${unusedVars.map(v => v.name).join(', ')}`);
    }

    // 处理每个变量的值
    context.variables.forEach(variable => {
      const value = context.values[variable.name] ?? variable.defaultValue;
      if (value !== undefined) {
        processedValues[variable.name] = this.processVariableValue(variable, value);
        // 更新缓存
        this.updateVariableMetadata(variable.name, processedValues[variable.name]);
      }
    });

    // 替换模板中的变量
    const result = replaceVariables(context.template, context.variables, processedValues);

    return {
      processedTemplate: result.replaced,
      processedValues,
      errors: errors.length > 0 ? errors : undefined,
      warnings: warnings.length > 0 ? warnings : undefined
    };
  }

  /**
   * 生成变量的初始值
   */
  generateInitialValues(variables: PromptVariable[]): Record<string, PromptVariableValue> {
    return generateInitialValues(variables);
  }

  /**
   * 批量处理变量
   */
  batchProcessVariables(
    templates: string[],
    variables: PromptVariable[],
    valuesList: Record<string, PromptVariableValue>[]
  ): VariableProcessResult[] {
    return templates.map((template, index) => {
      const values = valuesList[index] || {};
      return this.processTemplate({ template, variables, values });
    });
  }

  /**
   * 注册自定义预处理器
   */
  registerPreprocessor(name: string, processor: (value: any) => any) {
    this.preprocessors.set(name, processor);
  }

  /**
   * 更新变量元数据（用于统计）
   */
  private updateVariableMetadata(name: string, value: PromptVariableValue) {
    const existing = this.variableCache.get(name) || {
      name,
      usage: 0,
      commonValues: []
    };

    existing.usage++;
    existing.lastUsed = new Date();

    // 更新平均长度（字符串类型）
    if (typeof value === 'string') {
      const currentAvg = existing.averageLength || 0;
      existing.averageLength = (currentAvg * (existing.usage - 1) + value.length) / existing.usage;

      // 更新常用值
      if (!existing.commonValues) {
        existing.commonValues = [];
      }
      if (!existing.commonValues.includes(value) && existing.commonValues.length < 10) {
        existing.commonValues.push(value);
      }
    }

    this.variableCache.set(name, existing);
  }

  /**
   * 获取变量使用统计
   */
  getVariableStatistics(): VariableMetadata[] {
    return Array.from(this.variableCache.values())
      .sort((a, b) => b.usage - a.usage);
  }

  /**
   * 获取变量建议值
   */
  getSuggestedValues(variableName: string): string[] {
    const metadata = this.variableCache.get(variableName);
    return metadata?.commonValues || [];
  }

  /**
   * 导出变量配置
   */
  exportVariableConfig(variables: PromptVariable[]): string {
    return JSON.stringify(variables, null, 2);
  }

  /**
   * 导入变量配置
   */
  importVariableConfig(configJson: string): PromptVariable[] {
    try {
      const variables = JSON.parse(configJson);
      // 验证导入的数据结构
      if (!Array.isArray(variables)) {
        throw new Error('配置必须是数组格式');
      }
      variables.forEach(v => {
        if (!v.name || !v.type) {
          throw new Error('每个变量必须包含name和type字段');
        }
      });
      return variables;
    } catch (error) {
      throw new Error(`导入配置失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  /**
   * 创建变量模板
   */
  createVariableTemplate(
    name: string,
    type: PromptVariable['type'],
    options?: Partial<PromptVariable>
  ): PromptVariable {
    return {
      name,
      type,
      required: options?.required ?? false,
      description: options?.description,
      defaultValue: options?.defaultValue,
      options: options?.options,
      validation: options?.validation,
      min: options?.min,
      max: options?.max,
      preprocessor: options?.preprocessor,
      preprocessFunction: options?.preprocessFunction
    };
  }

  /**
   * 智能变量推断
   */
  inferVariableType(variableName: string, sampleValue?: any): PromptVariable['type'] {
    // 根据变量名推断类型
    const nameLower = variableName.toLowerCase();
    
    if (nameLower.includes('email')) return 'string';
    if (nameLower.includes('phone') || nameLower.includes('tel')) return 'string';
    if (nameLower.includes('url') || nameLower.includes('link')) return 'string';
    if (nameLower.includes('date') || nameLower.includes('time')) return 'string';
    if (nameLower.includes('age') || nameLower.includes('year') || 
        nameLower.includes('count') || nameLower.includes('number')) return 'number';
    if (nameLower.includes('enable') || nameLower.includes('disable') ||
        nameLower.includes('is') || nameLower.includes('has')) return 'boolean';
    
    // 根据样本值推断
    if (sampleValue !== undefined) {
      if (typeof sampleValue === 'boolean') return 'boolean';
      if (typeof sampleValue === 'number') return 'number';
      if (Array.isArray(sampleValue)) return 'select';
    }
    
    // 默认为字符串
    return 'string';
  }

  /**
   * 清理缓存
   */
  clearCache() {
    this.variableCache.clear();
  }
}

// 导出单例实例
export const variableManager = new VariableManagerService();

// 导出类用于测试
export { VariableManagerService };